﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace INSTA.AI97.EventsCreation
{

    /// DELEGATE STEP 1 
    // On déclare un delegate, tjs en dehors de la classe
    // ce qui définit un nouveau type référence (comme une classe),
    // et également une signature de méthode (ici void et sans arguments).
    public delegate void MessageDelegate();

    class Program
    {
        static void Main(string[] args)
        {
            //Test_MessageDelegate();
            Test_Event_NameChanged();
        }

        

        public static void Test_Event_NameChanged()
        {
            Person p = new Person();

            // On s'abonne à l'event "NameChanged" de notre
            // objet Person, et on lui abonne une procédure
            // nommée "SurChangementNom"
           p.NameChanged += new NameChangedDelegate(SurChangementNom);

            // On change la propriété Name, ce qui va déclencher
            // notre event.
           p.Name = "toto";

        }

        static void SurChangementNom(object sender, PersonEventArgs e)
        {
            //Person realSender = sender as Person;                  
            //Console.WriteLine("Le Nom a changé : " + realSender.Name);


            Console.WriteLine("Le nom de la Person est maitenant {0}",
                               e.NewName );

        }


                
        #region -- Demo des Delegates --

        public static void Test_MessageDelegate()
        {
            // DELEGATE STEP 2
            // On peut maintenant déclarer une variable du type
            // du delegate..
            MessageDelegate del;

            // DELEGATE STEP 3
            // On va maintenant instancier la variable de type MessageDelegate.
            // Le constructeur des delegates est tjs le même, et il prend 
            // en paramètre la méthode vers laquelle on veut qu'il "pointe".
            del = new MessageDelegate(SayHello);

            // DELEGATE STEP 4
            // On exécute le delegate, ce qui aura pour effet d'exécuter
            // la (ou les) méthode(s) stockées dans cette instance de delegate.
            del();

            Console.WriteLine();

            // DELEGATE STEP 3 (bis).
            // On peut "composer" un delegate, c.a.d lui ajouter x fois 
            // des méthodes à exécuter
            del += new MessageDelegate(SayHello);


            // on ré-exécute..
            del();

            Console.WriteLine();

            del += new MessageDelegate(SayGoodbye);
            del();

            Console.WriteLine();

            // DELEGATE STEP 5
            // On peut également supprimer d'une instance de delegate
            // une des méthodes que ce delegate contient avec l'opérateur -=
            Console.WriteLine("Après suppression deux fois de SayHello :");

            del -= new MessageDelegate(SayHello);
            del -= new MessageDelegate(SayHello);
            del();



        }


        public static void SayHello()
        {
            Console.WriteLine("Hello");
        }

        public static void SayGoodbye()
        {
            Console.WriteLine("Bye");
        } 
        #endregion
    }
}
